package com.sky.orangehireserver.modules.enterprise.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sky.orangehireserver.common.domain.Jobs;
import com.sky.orangehireserver.common.domain.Organization;
import com.sky.orangehireserver.common.domain.Users;
import com.sky.orangehireserver.common.service.JobsService;
import com.sky.orangehireserver.common.service.OrganizationService;
import com.sky.orangehireserver.common.service.UsersService;
import com.sky.orangehireserver.enums.ResponseCodeEnum;
import com.sky.orangehireserver.enums.UserRoleEnum;
import com.sky.orangehireserver.exception.BizException;
import com.sky.orangehireserver.modules.enterprise.dto.JobCreateDTO;
import com.sky.orangehireserver.modules.enterprise.dto.JobQueryDTO;
import com.sky.orangehireserver.modules.enterprise.dto.JobUpdateDTO;
import com.sky.orangehireserver.modules.enterprise.service.EnterpriseJobService;
import com.sky.orangehireserver.modules.enterprise.vo.JobVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 企业岗位管理服务实现类
 * 
 * @author sky
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class EnterpriseJobServiceImpl implements EnterpriseJobService {

    private final JobsService jobsService;
    private final OrganizationService organizationService;
    private final UsersService usersService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public JobVO createJob(Long orgId, Long ownerId, JobCreateDTO createDTO) {
        log.info("开始创建岗位，企业ID：{}，负责人ID：{}，岗位名称：{}", orgId, ownerId, createDTO.getTitle());
        
        // 检查企业是否存在且状态正常
        Organization organization = organizationService.getById(orgId);
        if (organization == null) {
            throw new BizException("ORGANIZATION_NOT_FOUND", "企业不存在");
        }
        if (!"active".equals(organization.getStatus())) {
            throw new BizException("ORGANIZATION_INACTIVE", "企业未激活，无法创建岗位");
        }
        
        // 检查负责人是否存在且属于该企业
        Users owner = usersService.getById(ownerId);
        if (owner == null) {
            throw new BizException("OWNER_NOT_FOUND", "职位负责人不存在");
        }
        if (!orgId.equals(owner.getOrgId())) {
            throw new BizException("OWNER_NOT_IN_ORG", "职位负责人不属于该企业");
        }
        if (!UserRoleEnum.isRecruiter(owner.getRole()) && !UserRoleEnum.isAdmin(owner.getRole())) {
            throw new BizException("INVALID_OWNER_ROLE", "只有企业管理员或HR可以作为职位负责人");
        }
        
        // 验证薪资范围
        if (createDTO.getSalaryMin() != null && createDTO.getSalaryMax() != null) {
            if (createDTO.getSalaryMin().compareTo(createDTO.getSalaryMax()) > 0) {
                throw new BizException("INVALID_SALARY_RANGE", "最低薪资不能大于最高薪资");
            }
        }
        
        // 创建岗位实体
        Jobs job = Jobs.builder()
                .orgId(orgId)
                .title(createDTO.getTitle())
                .department(createDTO.getDepartment())
                .location(createDTO.getLocation())
                .employmentType(createDTO.getEmploymentType())
                .seniority(createDTO.getSeniority())
                .education(createDTO.getEducation())
                .salaryMin(createDTO.getSalaryMin())
                .salaryMax(createDTO.getSalaryMax())
                .currency(createDTO.getCurrency() != null ? createDTO.getCurrency() : "CNY")
                .status("draft") // 新创建的岗位默认为草稿状态
                .ownerId(ownerId)
                .description(createDTO.getDescription())
                .requirements(createDTO.getRequirements())
                .responsibilities(createDTO.getResponsibilities())
                .benefits(createDTO.getBenefits())
                .tags(createDTO.getTags())
                .viewsCount(0)
                .applicationsCount(0)
                .createdAt(LocalDateTime.now())
                .updatedAt(LocalDateTime.now())
                .build();
        
        // 保存岗位
        boolean saved = jobsService.save(job);
        if (!saved) {
            throw new BizException(ResponseCodeEnum.SYSTEM_ERROR.getErrorCode(), "创建岗位失败");
        }
        
        log.info("岗位创建成功，岗位ID：{}", job.getId());
        return convertToVO(job, organization, owner);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public JobVO updateJob(Long orgId, JobUpdateDTO updateDTO) {
        log.info("开始更新岗位信息，企业ID：{}，岗位ID：{}", orgId, updateDTO.getId());
        
        // 检查岗位是否存在且属于该企业
        Jobs existingJob = jobsService.getById(updateDTO.getId());
        if (existingJob == null) {
            throw new BizException("JOB_NOT_FOUND", "岗位不存在");
        }
        if (!orgId.equals(existingJob.getOrgId())) {
            throw new BizException("JOB_NOT_IN_ORG", "岗位不属于该企业");
        }
        
        // 验证薪资范围
        BigDecimal salaryMin = updateDTO.getSalaryMin() != null ? updateDTO.getSalaryMin() : existingJob.getSalaryMin();
        BigDecimal salaryMax = updateDTO.getSalaryMax() != null ? updateDTO.getSalaryMax() : existingJob.getSalaryMax();
        if (salaryMin != null && salaryMax != null && salaryMin.compareTo(salaryMax) > 0) {
            throw new BizException("INVALID_SALARY_RANGE", "最低薪资不能大于最高薪资");
        }
        
        // 更新岗位信息（只更新非空字段）
        Jobs updateJob = new Jobs();
        updateJob.setId(updateDTO.getId());
        updateJob.setUpdatedAt(LocalDateTime.now());
        
        if (StrUtil.isNotBlank(updateDTO.getTitle())) {
            updateJob.setTitle(updateDTO.getTitle());
        }
        if (StrUtil.isNotBlank(updateDTO.getDepartment())) {
            updateJob.setDepartment(updateDTO.getDepartment());
        }
        if (StrUtil.isNotBlank(updateDTO.getLocation())) {
            updateJob.setLocation(updateDTO.getLocation());
        }
        if (StrUtil.isNotBlank(updateDTO.getEmploymentType())) {
            updateJob.setEmploymentType(updateDTO.getEmploymentType());
        }
        if (StrUtil.isNotBlank(updateDTO.getSeniority())) {
            updateJob.setSeniority(updateDTO.getSeniority());
        }
        if (StrUtil.isNotBlank(updateDTO.getEducation())) {
            updateJob.setEducation(updateDTO.getEducation());
        }
        if (updateDTO.getSalaryMin() != null) {
            updateJob.setSalaryMin(updateDTO.getSalaryMin());
        }
        if (updateDTO.getSalaryMax() != null) {
            updateJob.setSalaryMax(updateDTO.getSalaryMax());
        }
        if (StrUtil.isNotBlank(updateDTO.getCurrency())) {
            updateJob.setCurrency(updateDTO.getCurrency());
        }
        if (StrUtil.isNotBlank(updateDTO.getStatus())) {
            updateJob.setStatus(updateDTO.getStatus());
        }
        if (StrUtil.isNotBlank(updateDTO.getDescription())) {
            updateJob.setDescription(updateDTO.getDescription());
        }
        if (StrUtil.isNotBlank(updateDTO.getRequirements())) {
            updateJob.setRequirements(updateDTO.getRequirements());
        }
        if (StrUtil.isNotBlank(updateDTO.getResponsibilities())) {
            updateJob.setResponsibilities(updateDTO.getResponsibilities());
        }
        if (StrUtil.isNotBlank(updateDTO.getBenefits())) {
            updateJob.setBenefits(updateDTO.getBenefits());
        }
        if (StrUtil.isNotBlank(updateDTO.getTags())) {
            updateJob.setTags(updateDTO.getTags());
        }
        
        // 执行更新
        boolean updated = jobsService.updateById(updateJob);
        if (!updated) {
            throw new BizException(ResponseCodeEnum.SYSTEM_ERROR.getErrorCode(), "更新岗位信息失败");
        }
        
        // 返回更新后的岗位信息
        Jobs updatedJob = jobsService.getById(updateDTO.getId());
        Organization organization = organizationService.getById(updatedJob.getOrgId());
        Users owner = usersService.getById(updatedJob.getOwnerId());
        
        log.info("岗位信息更新成功，岗位ID：{}", updateDTO.getId());
        return convertToVO(updatedJob, organization, owner);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteJob(Long orgId, Long jobId) {
        log.info("开始删除岗位，企业ID：{}，岗位ID：{}", orgId, jobId);
        
        // 检查岗位是否存在且属于该企业
        Jobs job = jobsService.getById(jobId);
        if (job == null) {
            throw new BizException("JOB_NOT_FOUND", "岗位不存在");
        }
        if (!orgId.equals(job.getOrgId())) {
            throw new BizException("JOB_NOT_IN_ORG", "岗位不属于该企业");
        }
        
        // TODO: 检查岗位是否还有相关的投递记录，如果有则不允许删除
        // 这里可以根据业务需求添加相关检查逻辑
        
        // 执行删除
        boolean deleted = jobsService.removeById(jobId);
        if (!deleted) {
            throw new BizException(ResponseCodeEnum.SYSTEM_ERROR.getErrorCode(), "删除岗位失败");
        }
        
        log.info("岗位删除成功，岗位ID：{}", jobId);
    }

    @Override
    public JobVO getJobById(Long orgId, Long jobId) {
        log.info("查询岗位详情，企业ID：{}，岗位ID：{}", orgId, jobId);
        
        Jobs job = jobsService.getById(jobId);
        if (job == null) {
            throw new BizException("JOB_NOT_FOUND", "岗位不存在");
        }
        if (!orgId.equals(job.getOrgId())) {
            throw new BizException("JOB_NOT_IN_ORG", "岗位不属于该企业");
        }
        
        Organization organization = organizationService.getById(job.getOrgId());
        Users owner = usersService.getById(job.getOwnerId());
        
        return convertToVO(job, organization, owner);
    }

    @Override
    public IPage<JobVO> getJobPage(Long orgId, JobQueryDTO queryDTO) {
        log.info("分页查询岗位列表，企业ID：{}，查询条件：{}", orgId, queryDTO);
        
        // 构建查询条件
        LambdaQueryWrapper<Jobs> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Jobs::getOrgId, orgId)
                .like(StrUtil.isNotBlank(queryDTO.getTitle()), Jobs::getTitle, queryDTO.getTitle())
                .eq(StrUtil.isNotBlank(queryDTO.getDepartment()), Jobs::getDepartment, queryDTO.getDepartment())
                .eq(StrUtil.isNotBlank(queryDTO.getLocation()), Jobs::getLocation, queryDTO.getLocation())
                .eq(StrUtil.isNotBlank(queryDTO.getEmploymentType()), Jobs::getEmploymentType, queryDTO.getEmploymentType())
                .eq(StrUtil.isNotBlank(queryDTO.getSeniority()), Jobs::getSeniority, queryDTO.getSeniority())
                .eq(StrUtil.isNotBlank(queryDTO.getEducation()), Jobs::getEducation, queryDTO.getEducation())
                .eq(StrUtil.isNotBlank(queryDTO.getStatus()), Jobs::getStatus, queryDTO.getStatus())
                .eq(queryDTO.getOwnerId() != null, Jobs::getOwnerId, queryDTO.getOwnerId())
                .like(StrUtil.isNotBlank(queryDTO.getTags()), Jobs::getTags, queryDTO.getTags())
                .orderByDesc(Jobs::getCreatedAt);
        
        // 分页查询
        Page<Jobs> page = new Page<>(queryDTO.getCurrent(), queryDTO.getSize());
        IPage<Jobs> jobPage = jobsService.page(page, queryWrapper);
        
        // 获取企业和负责人信息映射
        Organization organization = organizationService.getById(orgId);
        List<Long> ownerIds = jobPage.getRecords().stream()
                .map(Jobs::getOwnerId)
                .distinct()
                .collect(Collectors.toList());
        
        Map<Long, Users> ownerMap = usersService.listByIds(ownerIds).stream()
                .collect(Collectors.toMap(Users::getId, user -> user));
        
        // 转换为VO
        IPage<JobVO> voPage = new Page<>(jobPage.getCurrent(), jobPage.getSize(), jobPage.getTotal());
        List<JobVO> voList = jobPage.getRecords().stream()
                .map(job -> convertToVO(job, organization, ownerMap.get(job.getOwnerId())))
                .collect(Collectors.toList());
        voPage.setRecords(voList);
        
        return voPage;
    }

    @Override
    public List<JobVO> getAllJobsByOrgId(Long orgId) {
        log.info("查询企业所有岗位列表，企业ID：{}", orgId);
        
        LambdaQueryWrapper<Jobs> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Jobs::getOrgId, orgId)
                .orderByDesc(Jobs::getCreatedAt);
        
        List<Jobs> jobs = jobsService.list(queryWrapper);
        
        // 获取企业和负责人信息
        Organization organization = organizationService.getById(orgId);
        List<Long> ownerIds = jobs.stream()
                .map(Jobs::getOwnerId)
                .distinct()
                .collect(Collectors.toList());
        
        Map<Long, Users> ownerMap = usersService.listByIds(ownerIds).stream()
                .collect(Collectors.toMap(Users::getId, user -> user));
        
        return jobs.stream()
                .map(job -> convertToVO(job, organization, ownerMap.get(job.getOwnerId())))
                .collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void publishJob(Long orgId, Long jobId) {
        log.info("发布岗位，企业ID：{}，岗位ID：{}", orgId, jobId);
        updateJobStatus(orgId, jobId, "open");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void closeJob(Long orgId, Long jobId) {
        log.info("关闭岗位，企业ID：{}，岗位ID：{}", orgId, jobId);
        updateJobStatus(orgId, jobId, "closed");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void reopenJob(Long orgId, Long jobId) {
        log.info("重新开放岗位，企业ID：{}，岗位ID：{}", orgId, jobId);
        updateJobStatus(orgId, jobId, "open");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchDeleteJobs(Long orgId, List<Long> jobIds) {
        log.info("批量删除岗位，企业ID：{}，岗位ID列表：{}", orgId, jobIds);
        
        if (jobIds == null || jobIds.isEmpty()) {
            throw new BizException(ResponseCodeEnum.PARAM_NOT_VALID.getErrorCode(), "岗位ID列表不能为空");
        }
        
        // 检查所有岗位是否都属于该企业
        List<Jobs> jobs = jobsService.listByIds(jobIds);
        for (Jobs job : jobs) {
            if (!orgId.equals(job.getOrgId())) {
                throw new BizException("JOB_NOT_IN_ORG", "存在不属于该企业的岗位");
            }
        }
        
        // TODO: 检查岗位是否还有相关的投递记录，如果有则不允许删除
        // 这里可以根据业务需求添加相关检查逻辑
        
        // 执行批量删除
        boolean deleted = jobsService.removeByIds(jobIds);
        if (!deleted) {
            throw new BizException(ResponseCodeEnum.SYSTEM_ERROR.getErrorCode(), "批量删除岗位失败");
        }
        
        log.info("批量删除岗位成功，删除数量：{}", jobIds.size());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void incrementViewsCount(Long jobId) {
        Jobs job = jobsService.getById(jobId);
        if (job != null) {
            Jobs updateJob = new Jobs();
            updateJob.setId(jobId);
            updateJob.setViewsCount(job.getViewsCount() + 1);
            updateJob.setUpdatedAt(LocalDateTime.now());
            jobsService.updateById(updateJob);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void incrementApplicationsCount(Long jobId) {
        Jobs job = jobsService.getById(jobId);
        if (job != null) {
            Jobs updateJob = new Jobs();
            updateJob.setId(jobId);
            updateJob.setApplicationsCount(job.getApplicationsCount() + 1);
            updateJob.setUpdatedAt(LocalDateTime.now());
            jobsService.updateById(updateJob);
        }
    }

    @Override
    public List<JobVO> getJobsByOwnerId(Long orgId, Long ownerId) {
        log.info("查询负责人的岗位列表，企业ID：{}，负责人ID：{}", orgId, ownerId);
        
        LambdaQueryWrapper<Jobs> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Jobs::getOrgId, orgId)
                .eq(Jobs::getOwnerId, ownerId)
                .orderByDesc(Jobs::getCreatedAt);
        
        List<Jobs> jobs = jobsService.list(queryWrapper);
        
        // 获取企业和负责人信息
        Organization organization = organizationService.getById(orgId);
        Users owner = usersService.getById(ownerId);
        
        return jobs.stream()
                .map(job -> convertToVO(job, organization, owner))
                .collect(Collectors.toList());
    }

    /**
     * 更新岗位状态
     * 
     * @param orgId 企业ID
     * @param jobId 岗位ID
     * @param status 状态
     */
    private void updateJobStatus(Long orgId, Long jobId, String status) {
        // 检查岗位是否存在且属于该企业
        Jobs job = jobsService.getById(jobId);
        if (job == null) {
            throw new BizException("JOB_NOT_FOUND", "岗位不存在");
        }
        if (!orgId.equals(job.getOrgId())) {
            throw new BizException("JOB_NOT_IN_ORG", "岗位不属于该企业");
        }
        
        // 更新状态
        Jobs updateJob = new Jobs();
        updateJob.setId(jobId);
        updateJob.setStatus(status);
        updateJob.setUpdatedAt(LocalDateTime.now());
        
        boolean updated = jobsService.updateById(updateJob);
        if (!updated) {
            throw new BizException(ResponseCodeEnum.SYSTEM_ERROR.getErrorCode(), "更新岗位状态失败");
        }
    }

    /**
     * 将Jobs实体转换为JobVO
     * 
     * @param job 岗位实体
     * @param organization 企业实体
     * @param owner 负责人实体
     * @return 岗位VO
     */
    private JobVO convertToVO(Jobs job, Organization organization, Users owner) {
        JobVO vo = BeanUtil.copyProperties(job, JobVO.class);
        
        // 设置企业信息
        if (organization != null) {
            vo.setOrgName(organization.getName());
        }
        
        // 设置负责人信息
        if (owner != null) {
            vo.setOwnerName(owner.getName());
        }
        
        // 设置工作类型名称
        vo.setEmploymentTypeName(getEmploymentTypeName(job.getEmploymentType()));
        
        // 设置经验要求名称
        vo.setSeniorityName(getSeniorityName(job.getSeniority()));
        
        // 设置学历要求名称
        vo.setEducationName(getEducationName(job.getEducation()));
        
        // 设置状态名称
        vo.setStatusName(getStatusName(job.getStatus()));
        
        // 设置薪资范围显示
        vo.setSalaryRange(formatSalaryRange(job.getSalaryMin(), job.getSalaryMax(), job.getCurrency()));
        
        return vo;
    }

    /**
     * 获取工作类型名称
     */
    private String getEmploymentTypeName(String employmentType) {
        if (employmentType == null) return null;
        return switch (employmentType) {
            case "full_time" -> "全职";
            case "part_time" -> "兼职";
            case "intern" -> "实习";
            case "contract" -> "合同工";
            default -> employmentType;
        };
    }

    /**
     * 获取经验要求名称
     */
    private String getSeniorityName(String seniority) {
        if (seniority == null) return null;
        return switch (seniority) {
            case "junior" -> "初级";
            case "mid" -> "中级";
            case "senior" -> "高级";
            default -> seniority;
        };
    }

    /**
     * 获取学历要求名称
     */
    private String getEducationName(String education) {
        if (education == null) return null;
        return switch (education) {
            case "bachelor" -> "本科";
            case "master" -> "硕士";
            case "phd" -> "博士";
            case "none" -> "不限";
            default -> education;
        };
    }

    /**
     * 获取状态名称
     */
    private String getStatusName(String status) {
        if (status == null) return null;
        return switch (status) {
            case "draft" -> "草稿";
            case "open" -> "开放";
            case "closed" -> "关闭";
            default -> status;
        };
    }

    /**
     * 格式化薪资范围显示
     */
    private String formatSalaryRange(BigDecimal salaryMin, BigDecimal salaryMax, String currency) {
        if (salaryMin == null && salaryMax == null) {
            return "面议";
        }
        
        String currencySymbol = currency != null ? currency : "CNY";
        
        if (salaryMin != null && salaryMax != null) {
            return salaryMin + "-" + salaryMax + " " + currencySymbol;
        } else if (salaryMin != null) {
            return salaryMin + "+ " + currencySymbol;
        } else {
            return "≤" + salaryMax + " " + currencySymbol;
        }
    }
}